﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace DBTool
{
    public class ParseVerifyManager
    {
        public void Verify( string[] verifyTableNameList, string selectedPath )
        {
            if (null == verifyTableNameList)
            {
                MessageBox.Show("verifyTableNameList Is Null", "ParserVerifyManager", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string exportVerifyPath = selectedPath + "/" + Config._reverseParseFolderName;

            DeleteTable( exportVerifyPath, verifyTableNameList );

            CreateReverseParsingTable( verifyTableNameList, exportVerifyPath );

            InsertTitleToTable( verifyTableNameList, exportVerifyPath );

            ReverseParsing_From_DB_To_Table( verifyTableNameList, exportVerifyPath );

            Compare_ParseTable_With_ReverseParseTable( verifyTableNameList, selectedPath );
        }

        private void DeleteTable( string exportPath, string[] verifyTableNameList )
        {
            foreach (string verifyTableName in verifyTableNameList)
            {
                string deletePath = exportPath + "/" + verifyTableName + Config._exportFileExt;

                //DeleteTable
                if ( true == File.Exists( deletePath ) )
                    File.Delete( deletePath );

                // Sync delete File
                while (true == File.Exists(deletePath)) { }
            }
        }

        private void CreateReverseParsingTable( string[] verifyTableList, string exportReverseParseFolderPath )
        {
            //CreateTable
            if (false == Directory.Exists(exportReverseParseFolderPath))
                Directory.CreateDirectory(exportReverseParseFolderPath);

            // Sync Create Directory
            while (false == Directory.Exists(exportReverseParseFolderPath)) { }

            foreach (string tableName in verifyTableList)
            {
                string createFilePath = exportReverseParseFolderPath + "/" + tableName + Config._exportFileExt;

                if (true == File.Exists(createFilePath))
                {
                    MessageBox.Show("Error. " + tableName + " is Exist", "File Is Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                StreamWriter fileWriter = new StreamWriter(createFilePath, false, Encoding.UTF8);
                fileWriter.Close();
            }
        }

        private void InsertTitleToTable( string[] verifyTableNameList, string exportReverseParseFolderPath )
        {
            foreach (string tableName in verifyTableNameList)
            {
                string filePath = exportReverseParseFolderPath + "/" + tableName + Config._exportFileExt;

                if (false == File.Exists(filePath))
                {
                    MessageBox.Show("Error. " + tableName + " is Not Exist", "File Is Not Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                string[] tableTitles = DBConnect.Instance.GetTableTitles(tableName);
                if (null == tableTitles)
                {
                    MessageBox.Show(tableName + " DB Columns Not Exist", "Table Title Not Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                string insertTitleRow = "";
                foreach (string column in tableTitles)
                {
                    insertTitleRow += column;
                    insertTitleRow += ",";
                }

                insertTitleRow = insertTitleRow.TrimEnd(',');
                insertTitleRow += "\r\n";

                File.AppendAllText(filePath, insertTitleRow);
            }
        }

        private void ReverseParsing_From_DB_To_Table( string[] verifyTableList, string exportReverseParseFolderPath )
        {
            foreach (string tableName in verifyTableList)
            {
                string filePath = exportReverseParseFolderPath + "/" + tableName + Config._exportFileExt;

                if (false == File.Exists(filePath))
                {
                    MessageBox.Show("Error. " + tableName + " is Not Exist", "File Is Not Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                string tableValues = DBConnect.Instance.GetTableValues( tableName );

                if ( true == string.IsNullOrEmpty(tableValues) )
                {
                    MessageBox.Show("Error. " + tableName + " Value Is Null", "GetDBTableValue", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                File.AppendAllText(filePath, tableValues);
            }
        }

        private void Compare_ParseTable_With_ReverseParseTable( string[] verifyTableNameList, string selectedPath )
        {
            foreach (string tableName in verifyTableNameList )
            {
                string parseTablePath = selectedPath + "/" + Config._parseFolderName + "/" + tableName + Config._exportFileExt;
                string reverseParseTablePath = selectedPath + "/" + Config._reverseParseFolderName + "/" + tableName + Config._exportFileExt;

                if (false == File.Exists(parseTablePath) || false == File.Exists(reverseParseTablePath))
                {
                    MessageBox.Show("Table Is None. tableName : " + tableName, "ParseFileIsNone", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                }

                CSVReader parseTable = new CSVReader( parseTablePath );
                CSVReader reverseParseTable = new CSVReader( reverseParseTablePath );

                if (true == parseTable.Compare(reverseParseTable))
                    continue;

                string[] titles = parseTable.GetColumnTitle();

                for ( int rowCount = 1; rowCount < parseTable.GetRowCount() ; ++rowCount )
                {
                    for( int columnCount = 0 ; columnCount < titles.Length ; ++columnCount )
                    {
                        if( parseTable.Find( rowCount, titles[columnCount] ) == reverseParseTable.Find( rowCount, titles[columnCount] ) )
                            continue;

                        MessageBox.Show("Verify Fail. TableName : " + tableName + "\n FirstColumn : " + titles[0] + ", value : " 
                                        + parseTable.Find(rowCount, titles[0]) 
                                        + "\n Title : " + titles[columnCount] + "\n row : " + rowCount + 
                                        "\n " +  parseTable.Find( rowCount, titles[columnCount] ) + " != " +  reverseParseTable.Find( rowCount, titles[columnCount] )
                                        , "Verify Fail", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
    }
}
